import arrayMethods from "./array";
import { isObject, def } from "../utils/index";
export default function observe(value) {
  // 判断是否为对象 不是则return
  if (!isObject(value)) {
    return;
  }
  // 观察者
  return new Observer(value);
}

function Observer(value) {
  // 数组使用 defineProperty 无法触发setter方法
  // 给监控过的对象 增加__ob__属性
  // value.__ob__ = this; 错误 将一直递归
  def(value, "__ob__", this);
  // 判断 value 是对象还是数组
  if (Array.isArray(value)) {
    value.__proto__ = arrayMethods;
    // 是数组
    this.observeArray(value);
  } else {
    // 是对象
    this.walk(value);
  }
}
// 遍历data中的key 执行响应式方法 defineReactive
Observer.prototype.walk = function (obj) {
  // 拿到对象中所有的key 重新定义
  const keys = Object.keys(obj);
  for (let i = 0; i < keys.length; i++) {
    defineReactive(obj, keys[i], obj[keys[i]]);
  }
};
Observer.prototype.observeArray = function (array) {
  for (let i = 0; i < array.length; i++) {
    observe(array[i]);
  }
};

// 响应式defineReactive
function defineReactive(obj, key, value) {
  // 递归调用 深度劫持
  observe(value);
  Object.defineProperty(obj, key, {
    enumerable: true,
    configurable: true,
    get() {
      console.log("获取响应式数据", value);
      return value;
    },
    set(newValue) {
      console.log("设置响应式数据", newValue);
      if (newValue === value) {
        return;
      }
      observe(newValue);
      value = newValue;
    },
  });
}
